<template>
    <!-- 登录容器 -->
    <div class="login_container">
        <!-- 登录盒子 -->
        <div class="login_box">
            <!-- 头像区域 -->
            <div class="avatar_box">
                <img src="../assets/images/avator.jpg" alt="" />
            </div>
            <!-- 登录表单区域 -->
            <!-- elementUI表单-数据绑定：利用model数据绑定 -->
            <!-- elementUI表单-表单验证：利用rules数据验证 -->
            <!-- 利用vue中的ref获取元素，即可对元素进行业务逻辑处理，当前要对表单进行重置 -->
            <el-form
                ref="loginFormRef"
                :model="loginForm"
                :rules="loginRules"
                label-width="0px"
                class="login_form"
            >
                <!-- 用户名，prop指定验证规则 -->
                <el-form-item prop="username">
                    <el-input
                        type="text"
                        v-model="loginForm.username"
                        prefix-icon="iconfont icon-user"
                    ></el-input>
                </el-form-item>
                <!-- 密码，prop指定验证规则 -->
                <el-form-item prop="password">
                    <el-input
                        type="password"
                        v-model="loginForm.password"
                        prefix-icon="iconfont icon-3702mima"
                    ></el-input>
                </el-form-item>
                <!-- 按钮 -->
                <el-form-item class="btns">
                    <el-button type="primary" @click="checkLoginData"
                        >登录</el-button
                    >
                    <el-button type="info" @click="resetLoginForm"
                        >重置</el-button
                    >
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            // 登录表单的数据绑定对象
            loginForm: {
                // 账号密码设置为数据库中准确的数据，方便开发调试
                username: 'admin',
                password: '123456',
            },
            // 登录表单的数据验证
            loginRules: {
                // 每项表单都是数组，数组中可以存储多项验证规则，验证规则为对象
                // 注意验证规则名称要与data中的属性一致，否则无法生效

                // 验证用户名是否合法
                username: [
                    // required：必填，message：提示信息，trigger：什么时候触发
                    { required: true, message: '请输入用户名', trigger: 'blur'},
                    // min最短，max最长
                    { min: 2, max: 12, message: '长度在 2 到 12 个字符', trigger: 'blur'},
                ],
                // 验证密码是否合法
                password: [
                    { required: true, message: '请输入密码', trigger: 'blur'},
                    { min: 6, max: 16, message: '长度在 6 到 16 个字符', trigger: 'blur'},
                ],
            },
        }
    },
    methods: {
        // 重置表单
        resetLoginForm() {
            // this指向当前组件
            // this.$refs获取结构中ref绑定的元素
            // resetFields()：elementUI表单项的重置方法，重置回当前data数据所绑定的默认值
            this.$refs.loginFormRef.resetFields()
        },
        // 登录发起请求前预验证，验证提交数据是否合法
        checkLoginData() {
            // validate()：elementUI表单项的预验证方法，验证数据是否符合验证规则中的格式
            // 优化promise对象，也就是优化异步操作，更好的得到结果
            this.$refs.loginFormRef.validate(async (valid) => {
                // 验证不通过，则不发起请求，结束程序
                if (!valid) return
                // 验证通过，则发起请求接收结果，只有data与status最常用，其他不怎么常用
                // 结构赋值获取data，并且重命名为res
                const { data: res } = await this.$http.post(
                    'login',
                    this.loginForm
                )
                // 判断状态码是否等于200，200则登录成功，数据库验证数据是否匹配成功
                // 使用elementUI中的弹框优化用户体验
                if (res.meta.status !== 200) {
                    return this.$message({
                        // 弹框消息，允许使用html片段，但是暴露HTML片段很危险，后期会遭到XSS攻击
                        // dangerouslyUseHTMLString: true,
                        message: '登陆失败',
                        type: 'error',
                        center: true,
                        // 弹框消息消失时间，毫秒
                        duration: 1500,
                    })
                }
                this.$message.success({
                    // dangerouslyUseHTMLString: true,
                    message: '登陆成功',
                    type: 'success',
                    center: true,
                    duration: 1500,
                })
                // 1. 登陆成功之后的token，保存到客户端的 sessionStorage 中
                //    1.1 项目中除了登陆之外的其他API接口，必须在登陆之后才能访问
                //    1.2 token 只应在当前网站打开期间生效，所以将 token 保存在 sessionStorage 中
                // localStorage是持久化的存储机制，sessionStorage是会话期间的存储机制，sessionStorage对于登录会话期间最合适
                window.sessionStorage.setItem('token', res.data.token)
                // 2. 通过编程式导航跳转到后台主页，路由地址是 /home
                this.$router.push('/home')
            })
        },
    },
}
</script>

<!-- scoped：防止样式冲突，只允许本组件中使用，每个组件只关心自己的样式并且不冲突 -->
<!-- lang="less"：样式从支持less语法 -->
<style lang="less" scoped>
.login_container {
    height: 100%;
}

.login_box {
    width: 450px;
    height: 300px;
    background-color: rgba(255, 255, 255, 0.7);
    border-radius: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    .avatar_box {
        position: absolute;
        left: 50%;
        transform: translate(-50%, -50%);
        height: 130px;
        width: 130px;
        padding: 10px;
        border: 1px solid #eee;
        border-radius: 50%;
        box-shadow: 0 0 10px #ddd;
        background-color: #fff;
        img {
            width: 100%;
            height: 100%;
            border-radius: 50%;
            background-color: #eee;
        }
    }
}

.login_form {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
}

.btns {
    display: flex;
    justify-content: center;
}
</style>